jQuery.fn.itip = function(param){
	return this.each(function(){
		var config=readConfig(param);
		var textModel = $(this).attr('itip');
		var title = $(this).attr('ititle');
		var obj = this ;
		var tip = null;
		var needToCloseTip = null;
		var needClose = true;
		var cacheText = null;
		
		$(this).hover(
			function(event){
				showTip(event.pageX + 15, event.pageY + 15);
			},
			function(event){
				closeTip();
			}
		);
	
		function showTip(x,y){
			setTimeout(function(){
				if (needToCloseTip!=null){
					$(needToCloseTip).remove();
				}
				tip = genTip(x,y);
				$(tip).hover(function(){
					needClose = false;
				},function(){
					needClose = true;
					closeTip();
				});
				$('body').append(tip);
				needToCloseTip = tip ;
				needClose = true ;
				setTipContent(tip,textModel,title,this,config);
			},config.delay);
		}
		
		function closeTip(){
			setTimeout(function(){
				if (needToCloseTip!=null){
					if (needClose){
						$(needToCloseTip).remove();
						needToCloseTip=null;
						needClose = false ;	
					}
				}
			},config.delay);
		}
	
		function _setAjaxTipContent(){
			$(tip).find('.i-tip-text').html("Loading...");
	        var timestamp = new Date().getTime(); 
	        $.ajax({
	            data: "itipts=" + timestamp,
	            type: 'get',
	            url: textModel.substring(4),
	            success: function(text){
					if (tip!=null){
						$(tip).find('.i-tip-title').html(title);
						$(tip).find('.i-tip-text').html(text);
						cacheText = text ; 
					}
	            },
	            error: function(text){
					if (tip != null) {
						$(tip).find('.i-tip-text').html("Load Failure!");
					}
	            }
	        });
		}
		
		function setTipContent(){
			if(title==null) title="";
			if(textModel==null) textModel="";
		    if (textModel.substring(0, 5) == "text:") {//for text
		        $(tip).find('.i-tip-title').html(title);
				$(tip).find('.i-tip-text').html(textModel.substring(5));
		    }else if (textModel.substring(0, 4) == "url:") {//for ajax tip
				if (config.ajaxCache && cacheText != null) {
					$(tip).find('.i-tip-title').html(title);
					$(tip).find('.i-tip-text').html(cacheText);
				}else {
					_setAjaxTipContent();
				}
			}else if (textModel.substring(0, 5) == "next:") {//for large tip
				var html = $($(obj).next()[0]).html();
				$(tip).find('.i-tip-title').html(title);
				$(tip).find('.i-tip-text').html(html);
		    }else{//default
				$(tip).find('.i-tip-title').html(title);
				$(tip).find('.i-tip-text').html(textModel);
			}
	}
	});
	function genTip(x,y){
		var tip = document.createElement("div");
		var shadow = document.createElement("div");
		var panel = document.createElement("div");
		var title = document.createElement("div");
		var text = document.createElement("div");
		
		$(tip).addClass("i-tip");
		$(shadow).addClass("i-tip-shadow");
		$(panel).addClass("i-tip-panel");
		$(title).addClass("i-tip-title");
		$(text).addClass("i-tip-text");
		
		$(panel).append(title);
		$(panel).append(text);
		$(shadow).append(panel);
		$(tip).append(shadow);
		
		$(tip).css("left",x);
		$(tip).css("top",y);
		
		return tip;
	}
	
	function readConfig (config){
		if (config==null) config = new Object();
		return {
			ajaxCache : config.ajaxCache!=null?config.ajaxCache:false,
			delay : config.delay!=null?config.delay:0
		};
	}
};
